/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.qmul.ns2.line;

import edu.qmul.ns2.DrawElement;
import edu.qmul.ns2.MainFrame;
import edu.qmul.ns2.agent.AgentLabel;
import edu.qmul.ns2.computer.NodeLabel;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import me.zhy.swing.LineSegmentComponent;
import me.zhy.swing.AWTUtilities;
import me.zhy.swing.Draggable;

/**
 *
 * @author Moon
 */
public class DrawLine extends MouseAdapter implements DrawElement {

    private JPanel infoPanel;
    private LinkProperty linkInfo;
    private int linkType;
    private final JToggleButton chooseButton;
    private BorderComponent label;
    private BorderComponent firstBorder;
    private NodeLabel first;

    public DrawLine(JToggleButton chooseButton, int lt) {
        this.linkType = lt;
        this.chooseButton = chooseButton;
    }

    private void drawLine(Container parent, final NodeLabel first, final NodeLabel last) {
        final LineSegmentComponent comp = new ExtendLineSegmentComponent(first, last, this.linkType);
        comp.setForeground(Color.BLACK);
        parent.add(comp, 0);

        comp.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                e.getComponent().requestFocus();
            }

            @Override
            public void mouseClicked(final MouseEvent evt) {
                if (evt.getButton() != MouseEvent.BUTTON3) {
                    return;
                }
                JPopupMenu menu = new JPopupMenu();
                JMenuItem setInfo = new JMenuItem("PROPERTY");
                setInfo.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        final MainFrame frame = (MainFrame) SwingUtilities.getAncestorOfClass(MainFrame.class, evt.getComponent());
                        linkInfo = new LinkProperty(frame, true);
                        linkInfo.setTitle("Link Property");
                        linkInfo.setVisible(true);
                        ((ExtendLineSegmentComponent) comp).setBandWidth(linkInfo.getBandWidthText());
                        ((ExtendLineSegmentComponent) comp).setDelay(linkInfo.getDelayText());
                        ((ExtendLineSegmentComponent) comp).setQueueType(linkInfo.getQueueTypeText());
                        ((ExtendLineSegmentComponent) comp).setLinkCost(linkInfo.getLinkCostText());
                    }
                });
                JMenuItem delete = new JMenuItem("DELETE");
                delete.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        AWTUtilities.remove(comp);
                    }
                });
                menu.add(setInfo);
                menu.add(delete);
                //TODO
                menu.show(evt.getComponent(), evt.getX(), evt.getY());
            }
        });
        comp.addFocusListener(new FocusListener() {

            /**
             * 当 Computer 组件获得焦点时触发的操作
             * @param e 焦点事件
             */
            @Override
            public void focusGained(FocusEvent e) {
                MainFrame frame = (MainFrame) SwingUtilities.getAncestorOfClass(MainFrame.class, e.getComponent());
                if (frame == null) {
                    return;
                }
                frame.setInfoComponent(infoPanel = new XYInfoPanel());
                ((XYInfoPanel) infoPanel).setStartNodeIDText(new Integer(first.getID()).toString());
                ((XYInfoPanel) infoPanel).setEndNodeIDText(new Integer(last.getID()).toString());
                ((XYInfoPanel) infoPanel).setX0(String.valueOf(comp.getX0()));
                ((XYInfoPanel) infoPanel).setY0(String.valueOf(comp.getY0()));
                ((XYInfoPanel) infoPanel).setX1(String.valueOf(comp.getX1()));
                ((XYInfoPanel) infoPanel).setY1(String.valueOf(comp.getY1()));
            }

            @Override
            public void focusLost(FocusEvent e) {
                /*
                MainFrame frame = (MainFrame) SwingUtilities.getAncestorOfClass(MainFrame.class, e.getComponent());
                if (frame == null) {
                return;
                }
                infoPanel = null;
                frame.setInfoComponent(null);
                 * 
                 */
            }
        });
        //((ExtendLineSegmentComponent) comp).setBandWidth(infoPanel.getBandWidthText());
        //((ExtendLineSegmentComponent) comp).setDelay(infoPanel.getDelayText());
        //((ExtendLineSegmentComponent) comp).setQueueType(infoPanel.getQueueTypeText());
        //((ExtendLineSegmentComponent) comp).setLinkCost(infoPanel.getLinkCostText());
        chooseButton.setSelected(true);
    }

    static class BorderComponent extends JComponent {

        @Override
        public boolean contains(int x, int y) {
            return false;
        }

        @Override
        public void setForeground(Color c) {
            setBorder(BorderFactory.createLineBorder(c));
        }
    }

    @Override
    public void start(Component comp) {
        Container container = (Container) comp;
        AWTUtilities.removeChildrenNotify(container);
        label = new BorderComponent();
        label.setForeground(Color.red);
        container.add(label);
    }

    @Override
    public void stop(Component comp) {
        if (!(comp instanceof Container)) {
            return;
        }
        Container container = (Container) comp;
        AWTUtilities.addChildrenNotify(container);
        label.setBounds(0, 0, 0, 0);
        container.remove(label);
        if (firstBorder != null) {
            firstBorder.setBounds(0, 0, 0, 0);
            container.remove(firstBorder);
            first = null;
            firstBorder = null;
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        Component comp = e.getComponent();
        if (!(comp instanceof Container)) {
            return;
        }
        Container container = (Container) comp;
        Component child = container.getComponentAt(e.getPoint());
        if (child == null || child == container || !(child instanceof Draggable)) {
            label.setBounds(0, 0, 0, 0);
        } else {
            label.setBounds(child.getX() - 5, child.getY() - 5, child.getWidth() + 10, child.getHeight() + 10);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        Component comp = e.getComponent();
        if (!(comp instanceof Container)) {
            return;
        }
        Container container = (Container) comp;
        Component child = container.getComponentAt(e.getPoint());
        if (child == null || child == container || !(child instanceof Draggable) || child == first) {
            return;
        }
        if (first == null) {
            firstBorder = new BorderComponent();
            firstBorder.setForeground(Color.RED);
            container.add(firstBorder);
            firstBorder.setBounds(child.getX() - 5, child.getY() - 5, child.getWidth() + 10, child.getHeight() + 10);
            try {
                first = (NodeLabel) child;
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(e.getComponent(), ex.getMessage());
            }

        } else {
            drawLine(container, first, (NodeLabel) child);
        }
    }
}
